package com.example.factory.api.facade.impl;

import com.example.factory.api.dto.DtoAuditDetails;
import com.example.factory.api.dto.DtoReport;
import com.example.factory.api.dto.DtoReporterReport;
import com.example.factory.api.dto.Response;
import com.example.factory.api.dto.assembler.ReportAssembler;
import com.example.factory.api.dto.form.DtoReportForm;
import com.example.factory.api.dto.form.DtoReporterReportForm;
import com.example.factory.api.facade.ReportFacade;
import com.example.factory.core.domain.ReportEquipment;
import com.example.factory.core.domain.ReportPlan;
import com.example.factory.core.domain.ReportStatus;
import com.example.factory.core.repository.ReportEquipmentRepository;
import com.example.factory.core.repository.ReportPlanRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author Lei Tao
 */
@Service
public class ReportFacadeImpl implements ReportFacade {
    private final ReportAssembler reportAssembler;
    private final ReportPlanRepository reportPlanRepository;
    private final ReportEquipmentRepository reportEquipmentRepository;


    @Autowired
    public ReportFacadeImpl(ReportAssembler reportAssembler, ReportPlanRepository reportPlanRepository, ReportEquipmentRepository reportEquipmentRepository) {
        this.reportAssembler = reportAssembler;
        this.reportPlanRepository = reportPlanRepository;
        this.reportEquipmentRepository = reportEquipmentRepository;

    }

    @Override
    @Transactional
    public Response<DtoReport> saveOrUpdate(DtoReportForm dtoReportForm) {
        ReportPlan reportPlan = reportAssembler.toReport(dtoReportForm);
        List<ReportEquipment> reportEquipments = reportPlan.getReportEquipments();
        reportPlan.setReportEquipments(reportEquipments);
        reportPlanRepository.save(reportPlan);
        for (ReportEquipment reportEquipment : reportEquipments) {
            reportEquipment.setReportPlan(reportPlan);
            reportEquipmentRepository.save(reportEquipment);
        }
        DtoReport dtoReport = reportAssembler.toDtoReport(reportPlan);
        return Response.success(dtoReport);
    }

    @Override
    public Response<List<DtoReport>> list() {
        List<ReportPlan> reportPlans = reportPlanRepository.selectAll();
        List<DtoReport> dtoReports = reportAssembler.toDtoReports(reportPlans);
        return Response.success(dtoReports);
    }

    @Override
    public Response<DtoReport> details(String reportGuid) {
        ReportPlan reportPlan = reportPlanRepository.findByGuidAndArchivedFalse(reportGuid);
        DtoReport dtoReport = reportAssembler.toDtoReport(reportPlan);
        return Response.success(dtoReport);
    }

    @Override
    public Response<Void> delete(String reportGuid) {
        ReportPlan reportPlan = reportPlanRepository.findByGuidAndArchivedFalse(reportGuid);
        reportPlan.archived();
        reportPlanRepository.save(reportPlan);
        return Response.success();
    }

    @Override
    public Response<List<DtoReport>> listByScorerGuid(String scorerGuid) {
        List<ReportPlan> reportPlans = reportPlanRepository.selectAllByScorer(scorerGuid);
        List<DtoReport> dtoReports = reportAssembler.toDtoReports(reportPlans);
        return Response.success(dtoReports);
    }

    @Override
    public Response<List<DtoReport>> listByDtoReporterGuid(String reporterGuid) {
        List<ReportPlan> reportPlans = reportPlanRepository.selectAllByReport(reporterGuid);
        List<DtoReport> dtoReports = reportAssembler.toDtoReports(reportPlans);
        return Response.success(dtoReports);
    }

    @Override
    public Response<DtoReporterReport> reportDetails(String reportGuid) {
        ReportPlan reportPlan = reportPlanRepository.findByGuidAndArchivedFalse(reportGuid);
        DtoReporterReport dtoReporterReport = reportAssembler.toDtoReporterReport(reportPlan);
        return Response.success(dtoReporterReport);
    }

    @Override
    public Response<Void> commit(DtoReporterReportForm dtoReporterReportForm) {
        ReportPlan reportPlan = reportPlanRepository.findByGuidAndArchivedFalse(dtoReporterReportForm.getReportPlanGuid());
        String content = dtoReporterReportForm.getContent();
        reportPlan.setContent(content);
        reportPlan.setReportStatus(ReportStatus.GRADING_PEOPLE_BACKFILL);
        reportPlanRepository.save(reportPlan);
        return Response.success();
    }

    @Override
    public Response<DtoReporterReport> audit(String reportGuid) {
        ReportPlan reportPlan = reportPlanRepository.findByGuidAndArchivedFalse(reportGuid);
        reportPlan.setReportStatus(ReportStatus.PASS_AUDIT);
        reportPlanRepository.save(reportPlan);
        DtoReporterReport dtoReporterReport = reportAssembler.toDtoReporterReport(reportPlan);
        return Response.success(dtoReporterReport);
    }

    @Override
    public Response<List<DtoAuditDetails>> auditDetails(String reportGuid) {
        ReportPlan reportPlan = reportPlanRepository.findByGuidAndArchivedFalse(reportGuid);
        List<DtoAuditDetails> dtoAuditDetails = reportAssembler.toDtoAuditDetails(reportPlan);
        return Response.success(dtoAuditDetails);
    }
}
